#include "space_war.h"


int str2int(char * p){
    int result = 0;
    char chr;
    for (int i = 0; i < column_max; i++)
    {
        chr = p[i];
        if (chr == '\n' || chr == ',' || chr == ';' || chr == '\0')
            break;
        result = result * 10 + chr - '0';
    }
    return result;
}

pos line_to_position(char* line){
    pos p;
    const double sigma = 0.5;
    // const double PI = 3.1415926;
    const int unit = 100000; //10w
    int quadrant = str2int(line + 2 * (pos_width + 1));// 0-3
    p.x = str2int(line) * ((quadrant == 1 || quadrant == 2) ? -1 : 1);
    p.y = str2int(line + pos_width + 1) * ((quadrant == 0 || quadrant == 1) ? 1 : -1);
    
    // int add_phase = quadrant / 2;//*PI
    // printf(line + pos_width + 1);
    int32_t r = sqrt(pow(p.x, 2) + pow(p.y, 2));//20w-100w
    p.theta = atan2(p.y, p.x);
    double temp = (double)(r % unit) / unit;
    p.r = r / unit - 1 + ((temp < sigma)? 0:1);
    p.r_cur = (double)(r) / unit - 1;
    return p;
}

void line_to_point(char*line, state *p1,state* p2, char flag){
    
    char *ret = memchr(line, ',', strlen(line));
    int point[] = {str2int(line), str2int(ret + 1)};
    p1->point = (flag == '0') ? point[0] : point[1];
    p2->point = (flag == '1') ? point[0] : point[1];
}
bool load_state(state *p1, state *p2, resource_data* resources, char *path, char flag){
    pos *resource = resources->pos;
    char chr[line_max * column_max];
    char * lines[line_max];
    for(int i =0; i < line_max; i++){
        lines[i] = chr + i * column_max;
    }

    // int line_num = load_response(lines, path);
    int line_num = load_file(lines, path, -1);
    if(line_num == -1){
        return false;
    }
    else{
        int attack_i[] = {0, 0}, clear_i[] = {0, 0}, resource_i = 0;
        for (int i = 0; i < line_num - 1; i++)
        {
            int kind = str2int(lines[i]);
            pos pos_t = line_to_position(lines[i] + 2);
            switch (kind)
            {
            case 0:
                p1->station_pos = pos_t;
                break;
            case 1:
                p2->station_pos = pos_t;
                break;
            case 2:
                p1->attack_units[attack_i[0]] = pos_t;
                attack_i[0]++;
                break;
            case 3:
                p2->attack_units[attack_i[1]] = pos_t;
                attack_i[1]++;
                break;
            case 4:
                p1->clear_units[clear_i[0]] = pos_t;
                clear_i[0]++;
                break;
            case 5:
                p2->clear_units[clear_i[1]] = pos_t;
                clear_i[1]++;
                break;
            case 6:
                resource[resource_i] = pos_t;
                resource_i++;
                break;
            default:
                break;
            }
        }
        p1->attack_number = attack_i[0];
        p2->attack_number = attack_i[1];
        p1->clear_number = clear_i[0];
        p2->clear_number = clear_i[1];
        resources->num = resource_i;
        line_to_point(lines[line_num - 1], p1,p2, flag);
        return true;
    }
}


void send_cmd(state p1,operation ops, char* path){

    char *hints[] = {"station:generation unit or move\n", "attack unit:move\n", "clear unit: move\n"};
    //station,attack,clear
    int ops_num[] = {2, 15, 15};
    uint8_t station_ops[] = {ops.station_ops, ops.station_move};
    uint8_t *attack_ops = ops.attack_ops;
    uint8_t *clear_ops = ops.clear_ops;
    uint8_t *all_ops[] = {station_ops, attack_ops, clear_ops};
    uint8_t start_line[] = {cmd_station_line, cmd_attack_line, cmd_clear_line};

    int line_num = sizeof(hints) / sizeof(hints[0]) + ops_num[0] + ops_num[1] + ops_num[2];
    char ch[line_num * cmd_column_max];
    char *lines[line_num];
    for (int i = 0; i < line_num; i++){
        lines[i] = ch + i * cmd_column_max;
    }

    for (int i = 0; i < sizeof(hints) / sizeof(hints[0]); i++){
        memcpy(lines[start_line[i] - 1], hints[i], min(int, strlen(hints[i]) + 1, cmd_column_max));
        for (int j = 0; j < ops_num[i]; j++){
            lines[start_line[i] + j][0] = (((i == 1 && j +1 > p1.attack_number) || (i == 2 && j + 1 > p1.clear_number))? 0 : all_ops[i][j]) + '0';
            lines[start_line[i] + j][1] = '\n';
            lines[start_line[i] + j][2] = '\0';
        }
    }
    if(!send_file(path, lines, line_num)){
        fprintf(stderr, "%s", path);
        fprintf(stderr, "文件写入失败\n");
    }
}

bool is_pos_equal(pos p1, pos p2){
    if(p1.x == p2.x && p1.y == p2.y){
        return true;
    }
    else{
        return false;
    }
}
bool is_refresh(char* path, pos origin){

    char line[column_max*2];
    char *lines[] = {line, line + column_max};
    if(load_file(lines, path, 1) == -1){
        return false;
    }
    else{
        for (int i = 0;i < 2; i++){
            if(lines[i][0] == '0' && !is_pos_equal(origin, line_to_position(lines[i] + 2))){
                return true;
            }
        }
        return false;
    }
}

void print_ops(operation ops){
    printf("station ops:%d\n", ops.station_ops);
    printf("station move:%d\n", ops.station_move);
    for (int i = 0; i < attack_max; i++){
        printf("attack_ops[%d]:%d\n", i, ops.attack_ops[i]);
    }
    for (int i = 0; i < clear_max; i++){
        printf("clear_ops[%d]:%d\n", i, ops.clear_ops[i]);
    }
}

int load_file(char **lines, char *path, int range){
    FILE *file = fopen(path, "r");
    int i;

    if(file == NULL){
        i = -1;
        // fprintf(stderr, "%s读取失败\n", path);
        return i;
    }
    else if (range < -1){
        i = -1;
        // fprintf(stderr, "load_file参数错误\n");
    }
    
    else if(range == -1){
        for (i = 0; fgets(lines[i],column_max,file); i++){
        }
    }
    else{
        for (i = 0; i <= range; i++){
            if(fgets(lines[i], column_max, file) == NULL){
                // printf("line[0]:%s\n", lines[0]);
                fprintf(stderr, "%s", path);
                fprintf(stderr, "文件%d行读取错误\n",i);
                i = -1;
                break;
            }
        }
    }
    fclose(file);
    return i;
}

void set_path(char *res_path, char *cmd_path, char flag){
    const int order_pos = 14;
    if(flag == '0'){
        res_path[order_pos] = '1';
        cmd_path[order_pos] = '1';
    }
    else if (flag == '1'){
        res_path[order_pos] = '2';
        cmd_path[order_pos] = '2';  
    }
    else{
        fprintf(stderr, "未知命令行参数\n");
        exit(1);
    }
}

bool send_file(char * path, char ** lines, int num){
    FILE *file = fopen(path, "w");
    if(file == NULL){
        return false;
    }
    else{
        bool result = true;
        for (int i = 0; i < num; i++){
            if(fputs(lines[i], file) == EOF){
                result = false;
                break;
            }
        }
        fclose(file);
        return result;
    }
}

int is_end(char * path){
    char line[line_max];
    char *lines[] = {line};
    char *player_win_message[] = {"p1 win!", "p2 win!"};
    if (load_file(lines, path, 0) != -1)
    {
        if(strncmp(player_win_message[0], line, strlen(player_win_message[0])) == 0){
            return 1;
        }
        else if (strncmp(player_win_message[1], line, strlen(player_win_message[1])) == 0){
            return 2;
        }
        else{
            return 0;
        }   
    }
    else{
        return 0;
    }
    
}
